package com.qf.proxy.util;

//import com.itextpdf.text.pdf.PdfReader;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author claud
 * 2018年8月15日18:25:28
 * 抽取的公共的httpclient
 */

public class HttpClientUtil {

    /**
     * 将各个httpclient获取的HttpResponse转化为相应的pdf
     */
    public static String convertToImg(CloseableHttpResponse response, String path) {
        String absPath = "";
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            try {
                byte[] buffer = EntityUtils.toByteArray(entity);
                String fileName = System.currentTimeMillis() + ".jpeg";
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                String time = format.format(new Date());
                createFile(path + "/" + time + "/", fileName, buffer);
                absPath = path + "/" + time + "/" + fileName;
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return absPath;
    }

    /**
     * 将各个httpclient获取的HttpResponse转化为相应的pdf
     */
    public static String convertToPdf(CloseableHttpResponse responce, String path) {
        String pdfPath = "";
        HttpEntity entity = responce.getEntity();
        if (entity != null) {
            try {
                byte[] buffer = EntityUtils.toByteArray(entity);
//                new PdfReader(buffer).close();
                String fileName = System.currentTimeMillis() + ".pdf";
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                String time = format.format(new Date());
                createFile(path + "/" + time + "/", fileName, buffer);
                pdfPath = path + "/" + time + "/" + fileName;
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return pdfPath;
    }

    /**
     * 转化各个httpclient返回的html
     */
    public static String parsingHtml(CloseableHttpResponse responce) throws Exception {
        String html = null;
        HttpEntity entity = responce.getEntity();
        if (entity != null) {
            html = EntityUtils.toString(entity, "UTF-8");
            html = html.replace("&nbsp;", " ");
        }
        return html;
    }

    /**
     * 根据各个资源的路径生成对应的pdf
     */
    private static void createFile(String filePath, String fileName, byte[] content)
            throws IOException {
        File folder = new File(filePath);
        if (!folder.exists() && !folder.isDirectory()) {
            System.out.println("文件夹路径不存在，创建路径:" + filePath);
            folder.mkdirs();
        }
        FileOutputStream fos = new FileOutputStream(filePath + "/" + fileName);
        fos.write(content);
        fos.close();
    }

    public static String getHtmlWithProxyAndGetMethod(String url) {
        ProxyInfo proxyInfo = ProxyInfo.getgcrIpProxy();
//        ProxyInfo proxyInfo = new ProxyInfo();
        HttpClientConfig clientConfig = new HttpClientConfig(proxyInfo, url, "", true);
        String s = HttpClientUtil.get(clientConfig);

        for (int i = 0; i < 3; i++) {
            if (StringUtils.isNotEmpty(s)) {
                break;
            }
            if (StringUtils.isEmpty(s)) {
                s = HttpClientUtil.get(clientConfig);
            }
        }

        return s;
    }

    /**
     * 通用的获取html的get方法
     */
    public static String get(HttpClientConfig config) {
        String html = null;
        for (int i = 1; i <= 3; i++) {
            CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(config.getCookieStore()).setDefaultCredentialsProvider(config.getCredsProvider()).build();
            HttpGet httpget = null;
            long time1 = System.currentTimeMillis();
            CloseableHttpResponse response = null;
            try {
                httpget = new HttpGet(config.getUrl());
                httpget.setConfig(config.getRequestConfig());
                httpget.addHeader(HttpHeaders.USER_AGENT, HttpClientConfig.USER_AGENT);
                if (!StringUtils.isEmpty(config.getRefer())) {
                    httpget.addHeader(HttpHeaders.REFERER, config.getRefer());
                }
                //添加相关的header
                if (config.getHeaderMap() != null) {
                    for (Map.Entry<String, String> entry : config.getHeaderMap().entrySet()) {
                        httpget.addHeader(entry.getKey(), entry.getValue());
                    }
                }
                try {
                    response = httpClient.execute(httpget);
                } catch (Exception e) {
//                    e.printStackTrace();
                }

                int resStatu = response.getStatusLine().getStatusCode();
                if (resStatu == HttpStatus.SC_OK) {
                    Header contentTypeHeader = response.getFirstHeader("Content-Type");
                    if (contentTypeHeader != null) {
                        String value = contentTypeHeader.getValue();
                        if (value.contains("application/pdf") || value.contains("application/octet-stream")) {
                            html = convertToPdf(response, config.getStoragePath());
                            if (!StringUtils.isEmpty(html)) {
                                return html;
                            }
                        }
                        if (value.contains("image/jpeg") || value.contains("image/png")) {
                            html = HttpClientUtil.convertToImg(response, config.getStoragePath());
                            return html;
                        }
                    }
                    html = HttpClientUtil.parsingHtml(response);
                    if (html != null) {
                        break;
                    }
                }
            } catch (Exception e) {
//                e.printStackTrace();
            } finally {
                httpClient.getConnectionManager().shutdown();
            }
        }
        return html;
    }


    /**
     * 通用的获取html的post方法
     */
    public static String postByMapArray(Map<String, String[]> map, HttpClientConfig config) {
        String html = "";
        for (int i = 1; i <= 3; i++) {
            CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(config.getCookieStore()).setDefaultCredentialsProvider(config.getCredsProvider()).build();
            HttpPost httppost = null;
            long time1 = System.currentTimeMillis();
            CloseableHttpResponse responce;
            try {
                httppost = new HttpPost(config.getUrl());
                List<NameValuePair> nvps = new ArrayList<>();
                if (map != null) {
                    for (Map.Entry<String, String[]> entry : map.entrySet()) {
                        for (int s = 0; s < entry.getValue().length; s++) {
                            nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()[s]));
                        }
                    }
                }
                httppost.setEntity(new UrlEncodedFormEntity(nvps, "utf8"));
                httppost.setConfig(config.getRequestConfig());
//                httppost.setHeader("Content-type", "application/x-www-form-urlencoded");
                httppost.addHeader(HttpHeaders.USER_AGENT, HttpClientConfig.USER_AGENT);
                if (!StringUtils.isEmpty(config.getRefer())) {
                    httppost.addHeader(HttpHeaders.REFERER, config.getRefer());
                }
                if (config.getHeaderMap() != null) {
                    for (Map.Entry<String, String> entry : config.getHeaderMap().entrySet()) {
                        httppost.addHeader(entry.getKey(), entry.getValue());
                    }
                }
                responce = httpClient.execute(httppost);
                int resStatu = responce.getStatusLine().getStatusCode();
//                +""+"---"+responce.getHeaders("Location")[0].getValue()
                if (resStatu == HttpStatus.SC_MOVED_TEMPORARILY || resStatu == HttpStatus.SC_MOVED_PERMANENTLY) {
                    Header header = responce.getFirstHeader("location");
                    HttpClientConfig login = new HttpClientConfig(new ProxyInfo(), header.getValue(), "https://www.nature.com/", true);
                    login.setCookieStore(config.getCookieStore());
                    html = HttpClientUtil.get(login);
//                    html = getHtml(cookieStore, redirectUrl, referer);
                    break;
                }
                if (resStatu == 499) {
                    html = HttpClientUtil.parsingHtml(responce);
                    System.out.println("499错误:" + html);
                }
                if (resStatu == HttpStatus.SC_OK) {
                    html = HttpClientUtil.parsingHtml(responce);
                    if (html != null) {
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                if (e.toString().contains("java.net.UnknownHostException")) {

                }
                if (e.toString().contains("connect time out")) {
                }
            } finally {
                httpClient.getConnectionManager().shutdown();
            }
        }
        return html;
    }

    /**
     * 打印cookie查看问题的方法
     */
    public static void printCookie(BasicCookieStore bcs) {
        List<Cookie> list = bcs.getCookies();
        for (Cookie c : list) {
            System.out.println("cookie信息:" + c.toString());
        }
    }

}
